(function(widow) {
    let _default = {
        method: 'GET',
        url: '',
        baseUrl: '',
        headers: {},
        dataType: 'JSON',
        data: null,
        params: null,
        cache: true
    }
    // 默认
    ajaxPromise.defaults = _default
    // 基于promise设计ajax
    let ajaxPromise = function(options) {
        let {
            url,
            baseUrl,
            data,
            dataType,
            headers,
            cache,
            params,
            method
        } = options

        // 将参数处理
        if (/^(GET|DELETE|HEAD|OPTIONS)$/.test(method)) {
            if (params) {
                url += `${ajaxPromise.check(url)}${ajaxPromise.formatData(params)}`
            }

            if (cache == false) {
                url += `${ajaxPromise.check(url)}_=${+new Date()}}`
            }
            data = null
        }
        else {
            // post
            if(data) {
                data = ajaxPromise.formatData(data)
            }
        }

        // 返回promise对象
        return new Promise((resolve, reject) => {
            let xhr = new XMLHttpRequest()
            xhr.open(method, `${baseUrl}${url}`)
            if(headers != null && typeof headers === 'object') {
                for(let key in headers) {
                    let val = headers[key]
                    if(/[\u4e00-u9fa5]/.test(val)) { // 校验请求头是否合法
                        val = encodeURIComponent(val)
                    }
                    xhr.setRequestHeader(key, headers[key])
                }
            }
            xhr.onreadystatechange = () => {
                if (xhr.readyState == 4) {
                    if(/^(2|3)\d{2}$/.test(xhr.status)) {
                        let result = xhr.responseText
                        dataType = dataType.toUpperCase()
                        dataType === 'JSON' ? result = JSON.parse(result) 
                        : (dataType === 'XML' ? result = xhr.responseXML : null)
                        resolve(result, xhr)
                        return
                    }
                    reject(xhr.statusText, xhr)
                }
            }
            xhr.send(data)
        })
    }
    ajaxPromise.check = function(url) {
        return url.indexOf('?') > -1 ? '&' : '?'
    } 
    ajaxPromise.formatData = function(obj) {
        let str = ''
        for(let key in obj) {
            if(obj.hasOwnProperty(key)) {
                str += `${key}=${obj[key]}&`
            }
        }
        return str.substring(0, str.length)
    }

    // get 系列
    ['get', 'head', 'delete', 'options'].forEach(item => {
        ajaxPromise[item] = (url, options = {}) => {
            options = {
                ..._default,
                ...options,
                url,
                method: item.toUpperCase()
            }
        return ajaxPromise(options)
        }
    })

    // post系列
    ['post', 'put', 'patch'].forEach(item => {
        ajaxPromise[item] = (url, options = {}, data = {}) => {
            options = {
                ..._default,
                ...options,
                url,
                method: item.toUpperCase(),
                data
            }
        return ajaxPromise(options)
        }
    })

    window.axios = ajaxPromise
})()